﻿
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

#if UNITY_EDITOR
using Sirenix.OdinInspector.Editor;
#endif
using Sirenix.Utilities;
using System.Collections;
using Sirenix.OdinInspector;


//[Serializable]
public class BaseTList<T, TValue> where T : System.Enum
{
    [SerializeField]
    [ValueDropdown("CustomAddStatsButton", IsUniqueList = true, DrawDropdownForListElements = false, DropdownTitle = "Modify Stats")]
    [ListDrawerSettings(DraggableItems = false, Expanded = true)]
    private List<BaseTValue<T, TValue>> stats = new List<BaseTValue<T, TValue>>();




    public BaseTValue<T, TValue> this[int index]
    {
        get { return this.stats[index]; }
        set { this.stats[index] = value; }
    }

    public int Count
    {
        get { return this.stats.Count; }
    }

    public TValue this[T type]
    {
        get
        {
            for (int i = 0; i < this.stats.Count; i++)
            {
                if (this.stats[i].TypeStr == type.ToString())
                {
                    return this.stats[i].Value;
                }
            }

            return default;
        }
        set
        {
            for (int i = 0; i < this.stats.Count; i++)
            {
                if (this.stats[i].TypeStr == type.ToString())
                {
                    var val = this.stats[i];
                    val.Value = value;
                    this.stats[i] = val;
                    return;
                }
            }

            this.stats.Add(new BaseTValue<T, TValue>(type, value));
        }
    }


    public BaseTValue<T, TValue> Find(Predicate<BaseTValue<T, TValue>> match)
    {
        return stats.Find(match);
    }

    public List<BaseTValue<T, TValue>> FindAll(Predicate<BaseTValue<T, TValue>> match)
    {
        return stats.FindAll(match);
    }
    public void Sort()
    {
        stats.Sort();
    }

    public void Sort(Comparison<BaseTValue<T, TValue>> comparison)
    {
        stats.Sort(comparison);
    }
    public void Sort(int index, int count, IComparer<BaseTValue<T, TValue>> comparer)
    {
        stats.Sort(index, count, comparer);
    }

    public void Add(T type)
    {
        stats.TryAdd(new BaseTValue<T, TValue>(type));
    }
    public void Add(T type, TValue value)
    {
        stats.TryAdd(new BaseTValue<T, TValue>(type, value));
    }

    public void SetStats(List<BaseTValue<T, TValue>> baseTs)
    {
        stats = baseTs;
    }

#if UNITY_EDITOR
    // Finds all available stat-types and excludes the types that the statList already contains, so we don't get multiple entries of the same type.
    private IEnumerable CustomAddStatsButton()
    {
        return Enum.GetValues(typeof(T)).Cast<T>()
            .Except(this.stats.Select(x => x.Type))
            .Select(x => new BaseTValue<T, TValue>(x))
            .AppendWith(this.stats)
            .Select(x => new ValueDropdownItem(x.Type.ToString(), x));
    }


#endif
}

#if UNITY_EDITOR

internal class BaseTListValueDrawer<T, TValue> : OdinValueDrawer<BaseTList<T, TValue>> where T : Enum
{
    protected override void DrawPropertyLayout(GUIContent label)
    {
        // This would be the "private List<StatValue> stats" field.
        this.Property.Children[0].Draw(label);
    }
}

#endif
